#pragma once

#if defined(__unix__) || defined(__APPLE__)
#include <pthread.h>
#include <stdlib.h>

#ifdef PTHREADALT_BINDCORE_NR
	#include <unix/coreaff.h>	
#endif

typedef struct
{
	void *(*start_routine)(void *);
	void *args;
} altpthreadargs_t;

/* 需要实现这个函数 */
extern void thread_initializer();

static inline void *__altpthread_intercepter(void *arg)
{
	void *ret;
	altpthreadargs_t *altpthreadargs = (altpthreadargs_t *)arg;
	if (!altpthreadargs) return NULL;
#ifdef PTHREADALT_BINDCORE_NR
	static cid_t tid = 0;
	cid_t core_id = faa(&tid, 1) % PTHREADALT_BINDCORE_NR;
	BIND_CORE(core_id);
#endif
	thread_initializer();
	ret = altpthreadargs->start_routine(altpthreadargs->args);
	free(altpthreadargs);
	return ret;
}

// 劫持
static inline int altpthread_create(pthread_t *newthread, pthread_attr_t *attr, void *(*start_routine)(void *), void *args)
{
	altpthreadargs_t *p = (altpthreadargs_t *)malloc(sizeof(altpthreadargs_t));
	if (!p) {
		*newthread = (pthread_t)NULL;
		return -1;
	}
	p->start_routine = start_routine;
	p->args = args;
	int ret = pthread_create(newthread, attr, __altpthread_intercepter, (void *)p);
	if (0 != ret)
	{
		free(p);
	}
	return ret;
}

// #ifndef PTHREADALT_CUSTOM_CONTRUCTOR
// __attribute__((constructor)) void __pthreadalt_init_contructor() { 
// 	fprintf(stderr, "start proc_initializer \n");
// 	proc_initializer(); 
// 	/*fprintf(stderr, "start thread_initializer \n");*/ 
// 	thread_initializer(); }
// #endif

#ifndef PTHREADALT_INTERNAL
	#warning "pthread create alternated by <pthreadalt.h>"
#endif

#define pthread_create		altpthread_create



#endif
